using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Core.Common.Monitor;
using Core.Expansion;
using Core.Function;
using Core.Monitors;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Tool.Common;
using Tool.Web.HttpHelper;
using Tool.Windows.Win32;
using static Core.Common.Global;

namespace Core.HandleMsg
{
	public static class Authorization
	{
		#region 正则
		private static class _Reg
		{
			public static Regex 动态监控 = new Regex("^(开|关|删)动态监控(?:Uid:)?(\\d+)$", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.Singleline);
			public static Regex 直播监控 = new Regex("^(开|关|删)直播监控(?:Uid:)?(\\d+)$", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.Singleline);
			public static Regex 番剧监控 = new Regex("^(开|关|删)番剧监控(ss|md)?(\\d+)$", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.Singleline);
			public static Regex 推文监控 = new Regex("^(开|关|删)推文监控(?:@)?([\\S]+)$", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.Singleline);
			public static Regex 油管监控 = new Regex("^(开|关|删)油管监控([\\w-]+)$", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.Singleline);
		}
		#endregion

		#region 指令
		static string hotImg;
		static string randImg;
		static Regex searchAnime;
		#endregion

		public static void Init()
		{
			hotImg = Win32Help.IniReadValue(AppDir + "高级设置.ini", "热门图片", "指令", "热门图片", 255);
			randImg = Win32Help.IniReadValue(AppDir + "高级设置.ini", "随机图片", "指令", "随机图片", 255);
			searchAnime = new Regex(Win32Help.IniReadValue(AppDir + "高级设置.ini", "番剧搜索", "指令", "番剧搜索", 255) + "(.+)", RegexOptions.IgnoreCase | RegexOptions.Compiled);
		}

		public static int Handle(long qun, long qq, string msg)
		{
			if (_Reg.动态监控.IsMatch(msg))
			{
				var temp = HandleMonitor<BiliDynamic>(_Reg.动态监控.Match(msg), DynamicInfo, qun);
				File.WriteAllText(AppDir + "动态监控.txt", JsonConvert.SerializeObject(DynamicInfo));
				return temp;
			}
			else if (_Reg.直播监控.IsMatch(msg))
			{
				var temp = HandleMonitor<BiliLive>(_Reg.直播监控.Match(msg), BiliLiveInfo, qun);
				File.WriteAllText(AppDir + "直播监控.txt", JsonConvert.SerializeObject(BiliLiveInfo));
				return temp;
			}
			else if (_Reg.推文监控.IsMatch(msg))
			{
				var temp = HandleMonitor<TweeterMonitor>(_Reg.推文监控.Match(msg), TweetInfo, qun);
				File.WriteAllText(AppDir + "推文监控.txt", JsonConvert.SerializeObject(TweetInfo));
				return temp;
			}
			else if (_Reg.番剧监控.IsMatch(msg))
			{
				Match match4 = _Reg.番剧监控.Match(msg);
				int type4 = GetType(match4.Groups[1].Value);
				if (type4 == -2) return 0;
				string id;
				if (match4.Groups[2].Value.ToLower() == "ss")
				{
					try
					{
						id = JObject.Parse(Encoding.UTF8.GetString(HttpNet.Get("https://api.imjad.cn/bilibili/?get=seasoninfo&season_id=" + match4.Groups[3].Value)))["result"]["media"]["media_id"].ToString();
					}
					catch (Exception)
					{
						CQ.SendGroupMessage(qun, "番剧信息获取失败，无法开启监控");
						return 1;
					}
				}
				else
				{
					id = match4.Groups[3].Value;
				}
				ModifyMonitor<BiliBangumi>(BangumiInfo, id, type4, qun);
				File.WriteAllText(AppDir + "番剧监控.txt", JsonConvert.SerializeObject(BangumiInfo));
				return 1;
			}
			else if (_Reg.油管监控.IsMatch(msg))
			{
				var temp = HandleMonitor<YoutubeLive>(_Reg.油管监控.Match(msg), YtbLiveInfo, qun);
				File.WriteAllText(AppDir + "油管监控.txt", JsonConvert.SerializeObject(YtbLiveInfo));
				return temp;
			}
			else if (Reg.BiliGif.IsMatch(msg))
			{
				Match match5 = Reg.BiliGif.Match(msg);
				int aid = 0;
				if (match5.Groups[1].Value.ToLower() == "av")
				{
					int.TryParse(match5.Groups[2].Value, out aid);
				}
				else if (match5.Groups[1].Value.ToLower() == "ep")
				{
					string value = match5.Groups[2].Value;
					JObject jObject = JObject.Parse(Encoding.UTF8.GetString(HttpNet.Get("https://api.imjad.cn/bilibili/?get=source&episode_id=" + value)));
					if (jObject.ContainsKey("result"))
					{
						aid = int.Parse(jObject["result"][0]["av_id"].ToString());
					}
					else
					{
						CQ.SendGroupMessage(qun, "找不到对应的aid,请确认是否输入正确");
						return 1;
					}
				}
				if (aid == 0)
				{
					CQ.SendGroupMessage(qun, "解析失败");
				}
				else
				{
					CQ.SendGroupMessage(qun, WaitMessage);
					if (BiliBili.CreateBiliGif(aid, out string errormessage))
					{
						CQ.SendGroupMessage(qun, CQ.Code_Image((ImagePath + aid + ".gif").HandleImagePath()));
					}
					else
					{
						CQ.SendGroupMessage(qun, "生成失败：" + errormessage);
					}
				}
				return 1;
			}
			else if (searchAnime.IsMatch(msg))
			{
				var match = searchAnime.Match(msg);
				var key = match.Groups[1].Value;
				CQ.SendGroupMessage(qun, CQ.Code_AT(qq) + Anime.GetList(key, qq));
				return 1;
			}
			else if (msg.ToUpper() == "热门COS")
			{
				CQ.SendGroupMessage(qun, WaitMessage);
				if (BiliBili.GetCosHot(out string content))
				{
					CQ.SendGroupMessage(qun, content);
				}
				else
				{
					CQ.SendGroupMessage(qun, "获取失败");
				}
				return 1;
			}
			else if (msg == hotImg)
			{
				bool r18, fhx, wait;
				r18 = ((Win32Help.IniReadValue(AppDir + "高级设置.ini", "热门图片", "允许R18", "关", 65535) == "开") ? true : false);
				fhx = ((Win32Help.IniReadValue(AppDir + "高级设置.ini", "热门图片", "R18防和谐", "关", 65535) == "开") ? true : false);
				wait = ((!(Win32Help.IniReadValue(AppDir + "高级设置.ini", "热门图片", "发送提示语", "开", 65535) == "关")) ? true : false);
				if (wait) CQ.SendGroupMessage(qun, WaitMessage);
				var data = Yande.GetHotImg(out string imgRating, r18 ? 7 : 3);
				if (data.Length < 1024)
				{
					CQ.SendGroupMessage(qun, "图片获取失败，请检查网络");
					return 1;
				}
				string img = ImagePath + TimeHelp.GetCurrentTimeUnix(true).ToString() + ".jpg";
				File.WriteAllBytes(img, data);
				if (fhx)
					img = imgRating == "Explicit" || imgRating == "Questionable" ? img.HandleImage(true) : img.HandleImage();
				CQ.SendGroupMessage(qun, CQ.Code_Image(img.HandleImagePath()));
				return 1;
			}
			else if (msg == randImg)
			{
				if (Win32Help.IniReadValue(AppDir + "高级设置.ini", "随机图片", "来源", "0", 16) == "1") return 0;
				CQ.SendGroupMessage(qun, Pixiv.GetRandImg());
				return 1;
			}
			//自定义图片放最后处理
			msg = msg.Replace("[", string.Empty).Replace("]", string.Empty);
			string text = Win32Help.IniReadValue(AppDir + "自定义出图-高级.ini", msg, "参数");
			if (!string.IsNullOrWhiteSpace(text))
			{
				if (Win32Help.IniReadValue(AppDir + "自定义出图-高级.ini", msg, "发送提示语", "开", 255) != "关")
				{
					CQ.SendGroupMessage(qun, WaitMessage);
				}
				int maxpage = 20;
				if (Win32Help.IniReadValue(AppDir + "自定义出图-高级.ini", msg, "错误检查", "关", 255) == "开")
				{
					int tagsPage = Yande.GetTagsPage(text);
					if (tagsPage == 0)
					{
						CQ.SendGroupMessage(qun, "该tag没有结果，请检查网络和tag");
						return 1;
					}
					else if (tagsPage < 20)
					{
						maxpage = tagsPage;
					}
				}
				if (!int.TryParse(Win32Help.IniReadValue(AppDir + "自定义出图-高级.ini", msg, "级别", "7", 255), out int rating))
					rating = 7;
				Task.Run(async () =>
				{
					List<Task> tasks = new List<Task>();
					if (!int.TryParse(Win32Help.IniReadValue(AppDir + "自定义出图-高级.ini", msg, "连发", "1", 255), out int count))
						count = 1;
					for (int i = 0; i < count; i++)
					{
						await Task.Delay(5);
						var task = Task.Run(() =>
						{
							string text2 = ImagePath + TimeHelp.GetCurrentTimeUnix(true).ToString() + ".jpg";
							byte[] imageByTags = Yande.GetImageByTags(text, out string imgRating, maxpage, rating);
							if (imageByTags.Length > 1024)
							{
								File.WriteAllBytes(text2, imageByTags);
								text2 = imgRating == "Explicit" || imgRating == "Questionable" ? text2.HandleImage(true) : text2.HandleImage();
								CQ.SendGroupMessage(qun, CQ.Code_Image(text2.HandleImagePath()));
							}
							else
							{
								CQ.SendGroupMessage(qun, "发生错误或未随机到指定类型的图片");
							}
						});
						tasks.Add(task);
					}
					Task.WaitAll(tasks.ToArray());
				}).Wait();
				return 1;
			}
			return 0;
		}

		private static int GetType(string type)
		{
			if (type != null)
			{
				if (type == "开")
				{
					return 1;
				}
				if (type == "关")
				{
					return 0;
				}
				if (type == "删")
				{
					return -1;
				}
			}
			return -2;
		}

		private static int HandleMonitor<T>(Match match, List<MonitorInfo> infos, long Qun) where T : Monitor
		{
			int type = GetType(match.Groups[1].Value);
			if (type != -2)
			{
				string flag = match.Groups[2].Value;
				ModifyMonitor<T>(infos, flag, type, Qun);
				return 1;
			}
			else return 0;
		}

		private static void ModifyMonitor<T>(List<MonitorInfo> infos, string flag, int status, long Qun) where T : Monitor
		{
			var type = typeof(T);
			var item = infos.Find((d) => d.flag == flag);
			if (status == -1)
			{
				if (item != null)
				{
					infos.Remove(item);
					if (hashTable.ContainsKey(type + flag))
					{
						var Monitor = hashTable[type + flag] as Monitor;
						Monitor.Close();
						hashTable.Remove(type + flag);
					}				
					CQ.SendGroupMessage(Qun, "已经删除了此监控");
				}
				else CQ.SendGroupMessage(Qun, "监控不存在");
			}
			else
			{
				//item为null的情况
				if (item == null)
				{
					if (status == 0) CQ.SendGroupMessage(Qun, "监控不存在");
					else
					{
						var temp = new MonitorInfo { flag = flag };
						temp.item.Add(new MonitorItem { num = Qun, status = status, type = 0 });
						infos.Add(temp);
						T dynamic = (T)Activator.CreateInstance(typeof(T), flag);
						dynamic.TimeInterval = MonitorFrequency;
						dynamic.Start();
						hashTable[type + flag] = dynamic;
						CQ.SendGroupMessage(Qun, "已经增加了此监控");
					}
				}
				else
				{
					var subItem = item.item.Find(e => e.num == Qun);
					if (status == 0)
					{
						//关闭监控
						if (subItem == null) CQ.SendGroupMessage(Qun, "此监控下没有本群的数据");
						else
						{
							subItem.status = 0;
							//判断此监控是否需要开启
							if (!NeedOpen(item))
							{
								var Monitor = hashTable[type + flag] as Monitor;
								Monitor.Close();
								hashTable.Remove(type + flag);
							}
							CQ.SendGroupMessage(Qun, "本群已经关闭了此监控");
						}
					}
					else
					{
						//开启监控
						if (subItem == null)
						{
							item.item.Add(new MonitorItem { status = 1, num = Qun, type = 0 });
						}
						else subItem.status = 1;
						if (!hashTable.Contains(type + flag))
						{
							T dynamic = (T)Activator.CreateInstance(typeof(T), flag);
							dynamic.TimeInterval = MonitorFrequency;
							dynamic.Start();
							hashTable[type + flag] = dynamic;
						}
						CQ.SendGroupMessage(Qun, "本群已经开启了此监控");
					}
				}
			}
		}
	}
}
